/**
 * MIT License
 * 
 * Copyright (c) 2024 - present @ ebraid
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef __EB_BUS_H__
#define __EB_BUS_H__


#include <kernel/initcall.h>
#include <kernel/kobject.h>
#include <kernel/driver.h>
#include <kernel/device.h>


/**
 * @name: bus type name
 * @kobj: kobject
 * @match: match function, return 0 is matched, otherwise failed
 * @probe: probe function
 * @remove: remove function
 */
struct bus_type {
    const char* name;
    struct kobj  kobj;
    struct kobj  drv_kobj;
    struct kobj  dev_kobj;
    int (*match)(struct device *dev, struct driver *drv);
    int (*probe)(struct device *dev);
    void (*remove)(struct device *dev);
};


#ifdef __cplusplus
extern "C" {
#endif


/**
 * @brief Check whether the bus has been registered
 * @param bus: bus type
 * @return true: registered, otherwise: unregistered
 * @note bus name must be unique, if has been registered, return false
 */
bool bus_is_registered(struct bus_type *bus);


/**
 * @brief Get bus name
 * @param bus: bus type
 * @return bus name, if not registered, return NULL
 * @note bus name must be unique
 */
const char *bus_get_name(struct bus_type *bus);


/**
 * @brief Register bus type
 * @param bus: bus type
 * @return 0: success, otherwise: fail
 */
int bus_register(struct bus_type *bus);


/**
 * @brief Unregister bus type
 * @param bus: bus type
 * @return none
 */
void bus_unregister(struct bus_type *bus);


/**
 * @brief Find the index of the match table according to the compatible name
 * @param table: match table
 * @param compatible: compatible name
 * @return index of the match table, otherwise: -1
 * @note compatible name must be unique
 */
int bus_attach_match_table(struct of_device_id *table, const char *compatible);


/**
 * @brief Find the index of the match table according to the device and driver name
 * @param dev_name: device name
 * @param drv_name: driver name
 * @return index of the match table, otherwise: -1
 * @note dev_name and drv_name should not be NULL
 */
int bus_attach_match_name(const char* dev_name, const char* drv_name);


/**
 * @brief Simple match function
 * @param dev: device
 * @param drv: driver
 */
int bus_simple_match(struct device *dev, struct driver *drv);


#ifdef __cplusplus
}
#endif


#endif //!__EB_BUS_H__